﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApAPPKineoForAppWholeTrajectoryPlanCommand
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.AutomaticPathPlanner;
using DnProcessSimulateCommands.AutomaticPathPlanner.Planner;
using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;


namespace DnProcessSimulateCommands;

public class CApAPPKineoForAppWholeTrajectoryPlanCommand : CApAPPPlanCommandBase
{
  private List<CApAPPKineoForAppTrajectoryCommand> m_allTrajectoryPlanCommands;
  private int m_currentTaskIndex;
  private long m_lastRefreshTime;
  private Stopwatch m_elapsedTimer;

  public CApAPPKineoForAppWholeTrajectoryPlanCommand(
    List<CApAPPTask> i_tasks,
    KiAppPathPlanningParamsEx i_pathPlanningParams)
    : base(i_tasks, i_pathPlanningParams)
  {
    this.m_currentTaskIndex = -1;
    this.m_allTrajectoryPlanCommands = new List<CApAPPKineoForAppTrajectoryCommand>();
    this.m_elapsedTimer = new Stopwatch();
    this.PlanningWasCancelled = false;
  }

  public List<CApAPPKineoForAppTrajectoryCommand> PlanCommands()
  {
    return this.m_allTrajectoryPlanCommands;
  }

  public override void Cancel() => this.PlanningWasCancelled = true;

  public override double GetProgress()
  {
    double num1 = 0.0;
    double num2 = (double) this.CountSubProblems();
    for (int index = 0; index < this.m_currentTaskIndex; ++index)
      num1 += 1.0 / num2;
    return num1 + this.GetProgress(this.m_currentTaskIndex) / num2;
  }

  public override double GetProgress(int i_subtaskRank)
  {
    double progress = 0.0;
    if (i_subtaskRank <= this.m_currentTaskIndex)
      progress = this.m_allTrajectoryPlanCommands[i_subtaskRank].GetProgress();
    return progress;
  }

  protected override bool DoStart(
    ref CApAPPPlanCommandBase.PlanSuccessEventArgs errEvtArgs)
  {
    bool o_trackEndReached = false;
    bool flag = false;
    bool i_success = true;
    string i_message = string.Empty;
    string i_details = string.Empty;
    foreach (CApAPPTask capAppTask in this.TasksToPlan)
    {
      if (!(capAppTask is CApAPPRoboticTask capAppRoboticTask) || !capAppRoboticTask.AreZonesWellDefined())
      {
        i_message = CApAPPMainWindowStringTable.ZoneDefinitionErrorTitleTrajectoryPlanning;
        i_details = CApAPPMainWindowStringTable.ZoneDefinitionErrorMsg;
        i_success = false;
      }
    }
    while (i_success && !flag && !this.PlanningWasCancelled)
    {
      i_success = this.StartNextPathPlanning(ref o_trackEndReached);
      if (i_success)
      {
        if (o_trackEndReached)
        {
          flag = true;
        }
        else
        {
          while (!this.m_allTrajectoryPlanCommands[this.m_currentTaskIndex].IsFinished() && !this.PlanningWasCancelled)
          {
            this.m_allTrajectoryPlanCommands[this.m_currentTaskIndex].OnIdle();
            this.RefreshProgressUI();
          }
          if (this.PlanningWasCancelled && !this.m_allTrajectoryPlanCommands[this.m_currentTaskIndex].IsFinished())
            this.m_allTrajectoryPlanCommands[this.m_currentTaskIndex].Cancel();
        }
      }
      else
      {
        flag = true;
        i_message = CApAPPMainWindowStringTable.KineoForAppTrajectoryPlanningErrorTitle;
        i_details = CApAPPMainWindowStringTable.KineoForAppTrajectoryPlanningErrorMessage;
      }
    }
    errEvtArgs = i_success ? new CApAPPPlanCommandBase.PlanSuccessEventArgs(false, i_message, i_details) : new CApAPPPlanCommandBase.PlanSuccessEventArgs(true);
    this.EndPlanning(i_success, errEvtArgs);
    return i_success;
  }

  private void RefreshProgressUI()
  {
    if (this.m_elapsedTimer.ElapsedMilliseconds - this.m_lastRefreshTime <= 500L)
      return;
    this.m_lastRefreshTime = this.m_elapsedTimer.ElapsedMilliseconds;
    this.UpdateProgress((object) this, new EventArgs());
    Application.DoEvents();
  }

  private bool StartNextPathPlanning(ref bool o_trackEndReached)
  {
    bool flag = true;
    ++this.m_currentTaskIndex;
    o_trackEndReached = false;
    if (this.m_currentTaskIndex >= this.TasksToPlan.Count)
    {
      o_trackEndReached = true;
    }
    else
    {
      this.m_allTrajectoryPlanCommands.Add(this.DoCreatePlanCommand(this.TasksToPlan[this.m_currentTaskIndex], this.PathPlanningParams));
      this.m_elapsedTimer.Start();
      flag = this.m_allTrajectoryPlanCommands.Last<CApAPPKineoForAppTrajectoryCommand>().StartPlanning();
      if (!flag)
        this.m_elapsedTimer.Reset();
    }
    return flag;
  }

  protected virtual CApAPPKineoForAppTrajectoryCommand DoCreatePlanCommand(
    CApAPPTask i_task,
    KiAppPathPlanningParamsEx i_pathPlanningParams)
  {
    return new CApAPPKineoForAppTrajectoryCommand(i_task, i_pathPlanningParams);
  }

  private void EndPlanning(
    bool i_success,
    CApAPPPlanCommandBase.PlanSuccessEventArgs planSuccessEventArgs)
  {
    if (i_success)
    {
      foreach (CApAPPTask capAppTask in this.TasksToPlan)
        capAppTask.UpdateTxOperation();
    }
    this.NotifyEndPlanning((object) this, planSuccessEventArgs);
    foreach (CApAPPTask capAppTask in this.TasksToPlan)
      capAppTask.RestoreInitialState();
  }

  public override int RetrieveIndexSubProblemFromWaypoint(CApAPPWaypoint i_wp) => 0;

  public override int CountSubProblems() => this.TasksToPlan.Count;

  public override long GetElapsedTime() => this.m_elapsedTimer.ElapsedMilliseconds;

  public override bool IsFinished(int taskIndex)
  {
    bool flag = false;
    if (taskIndex <= this.m_currentTaskIndex)
      flag = this.m_allTrajectoryPlanCommands[taskIndex].IsFinished();
    return flag;
  }

  internal override void AfterPlanningFailure()
  {
    foreach (CApAPPKineoForAppTrajectoryCommand trajectoryPlanCommand in this.m_allTrajectoryPlanCommands)
      trajectoryPlanCommand.UnFreezeOperationTree();
  }
}
